// 简化的音频服务 - 使用MediaSource实现流式播放

export class AudioService {
  constructor() {
    this.currentAudio = null
    this.isPlaying = false
    this.currentMessageId = null
    this.mediaSourceStreams = new Map()
    this.onPlayEnd = null
  }

  // 播放URL音频
  async playAudio(audioUrl, messageId = null) {
    this.stopAudio()
    if (!audioUrl) return

    this.currentAudio = new Audio(audioUrl)
    this.currentMessageId = messageId
    this.isPlaying = true

    this.currentAudio.onended = () => {
      this.isPlaying = false
      this.currentMessageId = null
      if (this.onPlayEnd) this.onPlayEnd(messageId)
    }
    this.currentAudio.onerror = () => {
      this.isPlaying = false
      if (this.onPlayEnd) this.onPlayEnd(messageId)
    }

    try {
      await this.currentAudio.play()
    } catch (error) {
      this.isPlaying = false
      throw error
    }
  }

  stopAudio() {
    if (this.currentAudio) {
      this.currentAudio.pause()
      this.currentAudio = null
    }

    this.mediaSourceStreams.forEach((stream, messageId) => {
      this.cleanupMediaSource(messageId)
    })

    this.isPlaying = false
    this.currentMessageId = null
  }

  // 处理流式音频数据
  async processAudioChunk(base64Data, messageId) {
    try {
      const audioData = this.base64ToBuffer(base64Data)

      if (!this.mediaSourceStreams.has(messageId)) {
        await this.initMediaSourceStream(messageId)
      }

      const stream = this.mediaSourceStreams.get(messageId)
      if (stream && stream.sourceBuffer) {
        stream.audioChunks.push(audioData)
        this.appendNextChunk(messageId)
      }
    } catch (error) {
      console.error('音频处理失败:', error)
    }
  }

  // 初始化MediaSource流
  async initMediaSourceStream(messageId) {
    if (!('MediaSource' in window)) {
      console.error('浏览器不支持MediaSource API')
      return
    }

    const mediaSource = new MediaSource()
    const stream = {
      mediaSource,
      sourceBuffer: null,
      audio: null,
      audioChunks: [],
      isEnded: false,
      firstChunkAdded: false,
      chunkCount: 0
    }

    stream.audio = new Audio()
    stream.audio.src = URL.createObjectURL(mediaSource)

    mediaSource.addEventListener('sourceopen', () => {
      try {
        const mimeType = 'audio/mpeg'
        if (!MediaSource.isTypeSupported(mimeType)) {
          console.error('不支持的音频格式')
          return
        }

        stream.sourceBuffer = mediaSource.addSourceBuffer(mimeType)

        stream.sourceBuffer.addEventListener('updateend', () => {
          stream.chunkCount++

          // 累积足够的数据后再播放,避免开头丢字
          if (!stream.firstChunkAdded && stream.sourceBuffer.buffered.length > 0) {
            stream.firstChunkAdded = true // 立即设置标志，防止重复调用play()
            stream.audio.play().then(() => {
              this.isPlaying = true
              this.currentMessageId = messageId
            }).catch(error => {
              console.error('播放失败:', error)
              // 如果播放失败（例如，由于浏览器自动播放策略），应正确清理状态
              this.isPlaying = false
              this.cleanupMediaSource(messageId)
            })
          }
          this.appendNextChunk(messageId)
        })
      } catch (error) {
        console.error('创建SourceBuffer失败:', error)
      }
    })

    this.mediaSourceStreams.set(messageId, stream)

    stream.audio.onended = () => {
      this.isPlaying = false
      this.currentMessageId = null
      this.cleanupMediaSource(messageId)
      if (this.onPlayEnd) this.onPlayEnd(messageId)
    }

    stream.audio.onerror = () => {
      this.isPlaying = false
      this.cleanupMediaSource(messageId)
      if (this.onPlayEnd) this.onPlayEnd(messageId)
    }
  }

  // 添加下一个音频chunk到SourceBuffer
  appendNextChunk(messageId) {
    const stream = this.mediaSourceStreams.get(messageId)
    if (!stream || !stream.sourceBuffer) return

    if (stream.sourceBuffer.updating) return

    if (stream.audioChunks.length > 0) {
      const chunk = stream.audioChunks.shift()
      try {
        stream.sourceBuffer.appendBuffer(chunk)
      } catch (error) {
        console.error('添加音频数据失败:', error)
      }
    } else if (stream.isEnded && stream.mediaSource.readyState === 'open') {
      try {
        stream.mediaSource.endOfStream()
      } catch (error) {
        console.error('结束MediaSource失败:', error)
      }
    }
  }

  // Base64转Buffer
  base64ToBuffer(base64) {
    const binary = atob(base64)
    const bytes = new Uint8Array(binary.length)
    for (let i = 0; i < binary.length; i++) {
      bytes[i] = binary.charCodeAt(i)
    }
    return bytes.buffer
  }

  // 停止指定消息的流式播放
  stopStream(messageId) {
    if (this.mediaSourceStreams.has(messageId)) {
      this.cleanupMediaSource(messageId)
    }

    if (this.currentMessageId === messageId) {
      this.isPlaying = false
      this.currentMessageId = null
    }
  }

  // 清理MediaSource资源
  cleanupMediaSource(messageId) {
    const stream = this.mediaSourceStreams.get(messageId)
    if (stream) {
      if (stream.audio) {
        stream.audio.pause()
        stream.audio.src = ''
        stream.audio = null
      }

      if (stream.mediaSource) {
        try {
          if (stream.mediaSource.readyState === 'open') {
            stream.mediaSource.endOfStream()
          }
        } catch (error) {
          console.error('结束MediaSource失败:', error)
        }
      }

      stream.sourceBuffer = null
      stream.audioChunks = []

      this.mediaSourceStreams.delete(messageId)
    }
  }

  // 标记流式播放结束
  endStream(messageId) {
    const stream = this.mediaSourceStreams.get(messageId)
    if (stream) {
      stream.isEnded = true
      this.appendNextChunk(messageId)
    }
  }

  isPlayingMessage(messageId) {
    return this.currentMessageId === messageId && this.isPlaying
  }
}

export const audioService = new AudioService()
